package com.strongbj.iot.devices.guis.respnose.handle;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.strongbj.core.util.ByteUtil;
import com.strongbj.iot.devices.dam.request.entity.ScreenCommandEntity;
import com.strongbj.iot.devices.dam.response.entity.SensorParamesEntity;
import com.strongbj.iot.devices.guis.message.GUISMessage;
import com.strongbj.iot.devices.guis.message.MQMessageOfGUIS;

import io.netty.channel.ChannelHandlerContext;

/**
 * 温度的处理
 * 
 * @author yuzhantao
 *
 */
public class GUISTemperatureHandle extends TemperatureHandle {
	private final static Logger logger = LogManager.getLogger(GUISTemperatureHandle.class);

	/**
	 * 帧头
	 */
	protected final static String COMMAND_HEADER = "EE";
	/**
	 * 帧尾
	 */
	protected final static String COMMAND_FOOTER = "FFFCFFFF";
	protected final static String COMMAND_CODE = "B112";

	@Override
	public boolean isHandle(GUISMessage t) {
		if (Integer.valueOf("85", 16).byteValue() == t.getCommand()) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public Object handle(ChannelHandlerContext ctx, GUISMessage t) {
		super.handle(ctx,t);
		if (t.getData() == null)
			return null;
		int temperatureCount = t.getData().length / 3; // 获取温度的数量
		if (temperatureCount == 0)
			return null;

		Map<Integer, Integer> uMap = new HashMap<>();
		List<Integer> us = new ArrayList<>();
		for (int i = 0; i < temperatureCount; i++) {
			int temp = (int) ByteUtil.byteArrToShort(t.getData(), i * 3 + 1) / 16;
			int u = t.getData()[i * 3];
			if (temp>0) {
				us.add(u);
			}
			uMap.put(u, temp);
			byte[] dd = new byte[2];
			System.arraycopy(t.getData(), i * 3 + 1, dd, 0, 2);
			logger.debug("[{}]温度:{} value:{}", u, ByteUtil.byteArrToHexString(dd), temp);
		}

		List<SensorParamesEntity> sensorList = new ArrayList<>();

		SensorParamesEntity sp1 = new SensorParamesEntity();
		if (us.size() > 0) {
			int u = this.clacPostion(40, us);
			logger.debug("前面上从第{}U获取数据", u);
			sp1.setSensorPosition(1);
			sp1.setSensorDatas(uMap.get(u));
			sp1.setSensorType(1);
			sensorList.add(sp1);
		}

		SensorParamesEntity sp2 = new SensorParamesEntity();
		if (us.size() > 0) {
			int u = this.clacPostion(20, us);
			logger.debug("前面中从第{}U获取数据", u);
			sp2.setSensorPosition(2);
			sp2.setSensorDatas(uMap.get(u));
			sp2.setSensorType(1);
			sensorList.add(sp2);
		}
		SensorParamesEntity sp3 = new SensorParamesEntity();
		if (us.size() > 0) {
			int u = this.clacPostion(2, us);
			logger.debug("前面下从第{}U获取数据", u);
			sp3.setSensorPosition(3);
			sp3.setSensorDatas(uMap.get(u));
			sp3.setSensorType(1);
			sensorList.add(sp3);
		}

		if (sensorList != null && sensorList.size() > 0) {
			String devCode = ByteUtil.byteArrToHexString(t.getHostNumber());
			JSONObject object = new JSONObject();
			object.put("devAddrCode", devCode);
			try {
				object.put("frontTop", String.valueOf(sensorList.get(0).getSensorDatas()));
			} catch (Exception e) {
				logger.error("", e);
			}
			try {
				object.put("frontMiddle", String.valueOf(sensorList.get(1).getSensorDatas()));
			} catch (Exception e) {
				logger.error("", e);
			}
			try {
				object.put("frontBottom", String.valueOf(sensorList.get(2).getSensorDatas()));
			} catch (Exception e) {
				logger.error("", e);
			}
			try {
				if (sensorList.size() >= 4) {
					object.put("backTop", String.valueOf(sensorList.get(3).getSensorDatas()));
				}
			} catch (Exception e) {
				logger.error("", e);
			}
			// TODO 后门两个温度暂时硬件未实现
//			object.put("backMiddle", String.valueOf(sensorList.get(4).getSensorDatas()));
//			object.put("backBottom", String.valueOf(sensorList.get(5).getSensorDatas()));
			logger.debug("收到温度数据：{}", object.toJSONString());
		}
		try {
			sendtempHistoryDataToScreen(ctx, t, sp1, sp2, sp3);
		} catch (Exception e) {
			logger.error("", e);
		}
		return null;
	}

	/**
	 * 发送温度数据到屏幕
	 * 
	 * @param ctx
	 * @param t
	 * @throws UnsupportedEncodingException
	 */
	private void sendtempHistoryDataToScreen(ChannelHandlerContext ctx, GUISMessage t, SensorParamesEntity se1,
			SensorParamesEntity se2, SensorParamesEntity se3) throws UnsupportedEncodingException {
		Map<Short, String> sensorMap = new HashMap<>();
		if (se1 != null) {
			sensorMap.put((short) se1.getSensorPosition(), String.valueOf(se1.getSensorDatas()) + "℃");
		}
		if (se2 != null) {
			sensorMap.put((short) se2.getSensorPosition(), String.valueOf(se2.getSensorDatas()) + "℃");
		}
		if (se3 != null) {
			sensorMap.put((short) se3.getSensorPosition(), String.valueOf(se3.getSensorDatas()) + "℃");
		}
		
		// 更新时间
		SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy年MM月dd日hh时mm分ss秒");
		String date = sDateFormat.format(new Date());
		sensorMap.put((short) 8, date);

		sendMessage(ctx, t.getHostNumber(), sensorMap);
	}

	private void sendMessage(ChannelHandlerContext ctx, byte[] devAddress, Map<Short, String> sensorMap)
			throws UnsupportedEncodingException {
		String datas = createSensorMessage(sensorMap);
		MQMessageOfGUIS mm = new MQMessageOfGUIS();
		ScreenCommandEntity sc = new ScreenCommandEntity();
		sc.setRackConverCode(ByteUtil.byteArrToHexString(devAddress));
		sc.setCommand(datas);
		mm.setAwsPostdata(JSON.toJSONString(sc));
		com.strongbj.iot.devices.guis.request.handle.TransmissionHandle th = new com.strongbj.iot.devices.guis.request.handle.TransmissionHandle();
		th.handle(ctx, mm);
	}

	private String createSensorMessage(Map<Short, String> sensorMap) throws UnsupportedEncodingException {
		StringBuffer sb = new StringBuffer(COMMAND_HEADER);
		sb.append(COMMAND_CODE);
		sb.append("0001"); // 界面id
		for (Entry<Short, String> item : sensorMap.entrySet()) {
			sb.append(ByteUtil.byteArrToHexString(ByteUtil.shortToByteArr(item.getKey()))); // 控件id
			byte[] datas = item.getValue().getBytes("GBK");
			short dataLen = (short) datas.length;
			sb.append(ByteUtil.byteArrToHexString(ByteUtil.shortToByteArr(dataLen))); // 控件内容长度
			sb.append(ByteUtil.byteArrToHexString(datas)); // 控件内容
		}
		sb.append(COMMAND_FOOTER);

		return sb.toString();
	}

	/**
	 * 计算从数组中找出最靠近目标值的值
	 * 
	 * @param dest   目标值
	 * @param intArr 查找的数组
	 * @return 返回最靠近指定目标的数值
	 */
	private int clacPostion(int dest, List<Integer> intArr) {
		int minVal = Integer.MAX_VALUE;
		int result = 0;
		for (int i : intArr) {
			if (Math.abs(dest - i) < minVal) {
				minVal = Math.abs(dest - i);
				result = i;
			}
		}
		return result;
	}
}
